package com.star.sync.elasticsearch.common;


import com.star.sync.elasticsearch.annotation.EsDataMapping;
import org.apache.commons.lang.StringUtils;
import org.reflections.Reflections;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * map转bean工具
 *
 * @author liu
 */
@Component
public class MapToBean {

    public static final char UNDERLINE_CHAR = '_';
    /**
     * 映射的map
     */
    private Map<String, Class> map_bean_mapper=new HashMap<>();

    public Map<String, Class> getMap_bean_mapper() {
        return map_bean_mapper;
    }


    /**
     * 实例数据类型并转类型
     *
     * @param map
     * @param tableName
     * @return
     * @throws Exception
     */
    public Object change(Map<String, Object> map, String tableName) throws Exception {
        if (map_bean_mapper.get(tableName) == null) {
            throw new Exception("没有找到配置类型，请修改配置文件");
        }
        Object instance = map_bean_mapper.get(tableName).newInstance();

        BeanUtilEx.copyProperties(instance, changeField(map));

        return instance;
    }

    private Map<String, Object> changeField(Map<String, Object> map) {
        Map<String, Object> result = new HashMap<>(map.size() * 2);
        map.forEach((k, v) -> {
            result.put(underline2Camel(k), v);
        });
        return result;
    }


    /**
     * 驼峰转下划线
     *
     * @param camelStr
     * @return
     */
    public static String camel2Underline(String camelStr) {

        if (StringUtils.isEmpty(camelStr)) {

            return StringUtils.EMPTY;
        }

        int len = camelStr.length();
        StringBuilder strb = new StringBuilder(len + len >> 1);
        for (int i = 0; i < len; i++) {

            char c = camelStr.charAt(i);
            if (Character.isUpperCase(c)) {

                strb.append(UNDERLINE_CHAR);
                strb.append(Character.toLowerCase(c));
            } else {

                strb.append(c);
            }
        }
        return strb.toString();
    }

    /**
     * 下划线转驼峰
     *
     * @param underlineStr
     * @return
     */
    public static String underline2Camel(String underlineStr) {

        if (StringUtils.isEmpty(underlineStr)) {

            return StringUtils.EMPTY;
        }

        int len = underlineStr.length();
        StringBuilder strb = new StringBuilder(len);
        for (int i = 0; i < len; i++) {

            char c = underlineStr.charAt(i);
            if (c == UNDERLINE_CHAR && (++i) < len) {

                c = underlineStr.charAt(i);
                strb.append(Character.toUpperCase(c));
            } else {

                strb.append(c);
            }
        }
        return strb.toString();
    }

    @PostConstruct
    private void initBean() {
        Reflections f = new Reflections("com.star.sync.elasticsearch.dto");
        Set<Class<?>> set = f.getTypesAnnotatedWith(EsDataMapping.class);

        for (Class<?> c : set) {
            EsDataMapping annotation = c.getAnnotation(EsDataMapping.class);
            map_bean_mapper.put(annotation.tableName(),c);
        }

    }

}
